//
//  JKDateTool.swift
//  ZhiHuDaily-Swift
//
//  Created by albert on 2018/3/8.
//  Copyright © 2018年 安永博. All rights reserved.
//

import UIKit

class JKDateTool: NSObject {
    
    /** 获取当前时间的时间戳 */
    public class func getCurrentTimeStamp() -> TimeInterval {
        
        let date = Date(timeIntervalSinceNow: 0)
        let timeStamp = date.timeIntervalSince1970
        
        return timeStamp
    }
    
    /**
     * 获取指定时间的时间戳
     * "yyyyMMddHHmmss"
     * "yyyy-MM-dd HH:mm:ss"
     * "yyyy-MM-dd HH:mm:ss.SSS" */
    public class func getTimeStampWithFormattedStr(formattedStr: String) -> TimeInterval {
        //时间格式
        let fmt = DateFormatter()//[[NSDateFormatter alloc] init]
        
        fmt.dateFormat = (formattedStr.count > 19) ? "yyyy-MM-dd HH:mm:ss.SSS" : "yyyy-MM-dd HH:mm:ss"
        
        if formattedStr.count == 14 {
            
            fmt.dateFormat = "yyyyMMddHHmmss"
        }
        
        let date = fmt.date(from: formattedStr)
        
        return (date?.timeIntervalSince1970)!
    }
    
    /** 将时间戳转换为格式化后的字符串 刚刚 几分钟前  几小时前... */
    public class func timeStrSinceTimeStamp(timeStamp: TimeInterval) -> String {
        //时间格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        //帖子的创建时间
        //_create_time = "2015-12-31 21:40:29"
        let createDate = fmt.date(from: timeStrWithTimeStamp(timestamp: timeStamp, format: nil))
        if createDate!.isThisYear() { // 今年
            
            if createDate!.isToday() { // 今天
                //日历是currentCalendar！！！
                //NSCalendar *calendar = [NSCalendar currentCalendar]
                //NSDateComponents *cmps = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:create toDate:[NSDate date] options:0]
                
                //也可以直接用分类的类方法或对象方法直接计算时间差
                //NSDateComponents *cmps = [NSDate deltaFromeDate:create toDate:[NSDate date]]
                let cmps = Date().deltaFromDate(date: createDate!)
                
                if (cmps.hour! >= 1) { // 1小时以上
                    
                    fmt.dateFormat = String(format: "%d小时前", cmps.hour!)
                    
                    return fmt.string(from: createDate!)
                    
                }else if (cmps.minute! >= 1){ // 1小时以内，1分钟以上
                    
                    fmt.dateFormat = String(format: "%d分钟前", cmps.minute!)
                    
                    return fmt.string(from: createDate!)
                    
                }else{ // 1分钟以内
                    
                    fmt.dateFormat = "刚刚"
                    
                    return fmt.string(from: createDate!)
                }
                
            }else if createDate!.isYesterday() { // 昨天
                
                fmt.dateFormat = "昨天 HH:mm:ss"
                
                return fmt.string(from: createDate!)
                
            }else{ // 其它
                
                fmt.dateFormat = "MM-dd HH:mm:ss"
                
                return fmt.string(from: createDate!)
            }
            
        }else{//非今年
            return timeStrWithTimeStamp(timestamp: timeStamp, format: nil)
        }
    }
    
    /** 将时间戳转换为格式化的时间字符串 今天 昨天... */
    public class func timeStrFormattedWithTimeStamp(timestamp: TimeInterval) -> String {
        
        // 返回时间格式
        // currentDate 2015-09-28 16:28:09 +0000
        // msgDate 2015-09-28 10:36:22 +0000
        let calendar = Calendar.current
        // 1.获取当前的时间
        let currentDate = Date()
        
        // 获取年，月，日
        let componentsSet = Set<Calendar.Component>([.year, .month, .day])
        var components = calendar.dateComponents(componentsSet, from: currentDate)
        
        let currentYear = components.year
        let currentMonth = components.month
        let currentDay = components.day
        
        
        // 2.获取时间戳时间
        let stampDate = Date(timeIntervalSince1970: timestamp)
        
        // 获取年，月，日
        components = calendar.dateComponents(componentsSet, from: stampDate)
        let msgYear = components.year
        let msgMonth = components.month
        let msgDay = components.day
        
        
        // 3.判断:
        /* 今天：(HH:mm)
         * 昨天: (昨天 HH:mm)
         * 昨天以前:（2015-09-26 15:27） */
        
        let dateFmt = DateFormatter()
        if (currentYear == msgYear
            && currentMonth == msgMonth
            && currentDay == msgDay) { // 今天
            dateFmt.dateFormat = "今天 HH:mm"
            
        }else if(currentYear == msgYear
            && currentMonth == msgMonth
            && currentDay! - 1 == msgDay){ // 昨天
            
            dateFmt.dateFormat = "昨天 HH:mm"
        }else if(currentYear == msgYear
            && currentMonth == msgMonth
            && currentDay! - 2 == msgDay) { // 昨天以前
            
            dateFmt.dateFormat = "MM-dd HH:mm"
            
        }else{
            
            dateFmt.dateFormat = "yyyy-MM-dd HH:mm"
        }
        
        return dateFmt.string(from: stampDate)
    }
    
    /** 将时间戳转换为时间字符串 */
    public class func timeStrWithTimeStamp(timestamp: TimeInterval, format: String?) -> String {
        
        // 获取时间戳时间
        let stampDate = Date(timeIntervalSince1970: timestamp)
        
        let dateFmt = DateFormatter()
        
        dateFmt.dateFormat = (format != nil) ? format : "yyyy-MM-dd HH:mm:ss"
        
        return dateFmt.string(from: stampDate)
    }
    
    /** 将NSDate转换为时间字符串 格式可自定义，若传nil则默认返回值格式：2016-08-19 12:59:00 */public class func timeStrWithDate(date: Date, format: String?) -> String {
        
        let dateFmt = DateFormatter()
        
        dateFmt.dateFormat = (format != nil) ? format : "yyyy-MM-dd HH:mm:ss"
        
        
        return dateFmt.string(from: date)
    }
    
    /** 将时间戳转换为带毫秒的时间字符串 返回值格式：2016-08-19 12:59:00:000 */
    public class func timeStrMillisecondWithTimeStamp(timestamp: TimeInterval) -> String {
        
        // 获取时间戳时间
        let stampDate = Date(timeIntervalSince1970: timestamp)
        
        let dateFmt = DateFormatter()
        
        dateFmt.dateFormat = "yyyy-MM-dd HH:mm:ss:SSS"
        
        return dateFmt.string(from: stampDate)
    }
    
    /** 获取指定日期的前一天 参数格式："20160819" */
    public class func getPreviousDayOfSpecifiedDate(date: String) -> String {
        
        return getRelatedDateOfSpecifiedDate(date: date, year: 0, month: 0, day: -1)
    }
    
    /** 获取指定日期的后一天 参数格式："20160819" */
    public class func getNextDayOfSpecifiedDate(date: String) -> String {
        
        return getRelatedDateOfSpecifiedDate(date: date, year: 0, month: 0, day: 1)
    }
    
    /** 获取今天的日期 返回值格式："20160819" */
    public class func getDateOfToday() -> String{
        
        // 日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyyMMdd"
        let todayStr = fmt.string(from: Date())
        
        return todayStr
    }
    
    /** 获取今天的日期和时间字符串 返回值格式："2016-08-19 12:59:00" */
    public class func getDateAndTimeStrOfToday() -> String {
        
        // 日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        return fmt.string(from: Date())
    }
    
    /** 判断两个日期是否在同一个星期 参数格式: "20160819" */
    public class func isInTheSameWeek(date: String, anotherDate: String) -> Bool {
        
        if (date == "0" || anotherDate == "0") { return false }
        
        if (date == anotherDate) { return true }
        
        let MonDay1 = getMondayOfSpecifiedDate(date: date)
        let MonDay2 = getMondayOfSpecifiedDate(date: anotherDate)
        
        return MonDay1 == MonDay2
    }
    
    /** 获取指定日期的周一的日期 参数和返回值格式: "20160819" */
    public class func getMondayOfSpecifiedDate(date: String) -> String {
        
        var monday = getWeekdayOfSpecifiedDate(date: date)
        
        if monday == "星期一" { return date }
        
        var resultDate = ""
        
        for _ in 0 ..< 7 {
            
            resultDate = getPreviousDayOfSpecifiedDate(date: date)
            monday = getWeekdayOfSpecifiedDate(date: date)
            
            if monday == "星期一" {  break }
        }
        
        return resultDate
    }
    
    /** 获取今天的星期 */
    public class func getWeekdayOfToday() -> String {
        
        return getWeekdayOfSpecifiedDate(date: getDateOfToday())
    }
    
    /** 获取指定日期的星期 参数格式："20160819" */
    public class func getWeekdayOfSpecifiedDate(date: String) -> String {
        
        let weekdays = ["0.0", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
        
        // 日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyyMMdd"
        let specifiedDate = fmt.date(from: date)
        
        
        let calendar = Calendar(identifier: .gregorian)
        
        //NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:"Asia/Shanghai"]
        
        //[calendar setTimeZone: timeZone]
        
        let componentsSet = Set<Calendar.Component>([.weekday])
        
        let comp = calendar.dateComponents(componentsSet, from: specifiedDate!)
        
        return weekdays[comp.weekday!]
    }
    
    /**
     * date参数及返回值格式："2016081"
     * year=1表示1年后的时间 year=-1为1年前的日期 month day 类推
     */
    private class func getRelatedDateOfSpecifiedDate(date: String, year: Int, month: Int, day: Int) -> String {
        
        // 日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyyMMdd"
        let specifiedDate = fmt.date(from: date)
        
        let calendar = Calendar(identifier: .gregorian)
        
        // 比较日期
        var deltaComp = DateComponents()
        
        // 这个是获取当前时间差的date的 其中 year=1表示1年后的时间 year=-1为1年前的日期 month day 类推
        deltaComp.year = year
        deltaComp.month = month
        deltaComp.day = day
        
        let newDate = calendar.date(byAdding: deltaComp, to: specifiedDate!)
        
        let newDateStr = fmt.string(from: newDate!)
        
        return newDateStr
    }
    
    /** 计算某时间戳和当前时间的差值 返回值单位s 正数表示该时间戳在当前时间之后 */
    public class func calculateIntervalSinceNowWithTimeStamp(timeStamp: TimeInterval) -> TimeInterval {
        
        let time = timeStrWithTimeStamp(timestamp: timeStamp, format: nil)
        
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let date = fmt.date(from: time)
        
        let delta = date?.timeIntervalSince(Date())
        
        return delta!
    }
    
    /** 比较两个时间戳是否为同一天 */
    public class func isTimeStampTheSameDay(timeStamp: TimeInterval, anotherTimeStamp: TimeInterval) -> Bool {
        
        let date1 = Date(timeIntervalSince1970: timeStamp)
        let date2 = Date(timeIntervalSince1970: anotherTimeStamp)
        
        let calendar = Calendar.current
        let componentsSet = Set<Calendar.Component>([.year, .month, .day])
        
        
        let comp1 = calendar.dateComponents(componentsSet, from: date1)
        let comp2 = calendar.dateComponents(componentsSet, from: date2)
        
        return comp1.day  == comp2.day &&
            comp1.month == comp2.month &&
            comp1.year  == comp2.year
    }
    
    
    
    
    /**
     *  计算从startTingDate到resultDate相差的时间
     */
    public class func deltaFromDate(startTingDate: Date, toDate: Date) -> DateComponents {
        
        return Date.deltaFromeDate(startTingDate: startTingDate, toDate: toDate)
    }
    
    /**
     *  是否为今年
     */
    public class func isThisYear(date: Date) -> Bool {
        
        return date.isThisYear()
    }
    
    /**
     *  是否为今天
     */
    public class func isToday(date: Date) -> Bool {
    
        return date.isToday()
    }
    
    /**
     *  是否为昨天
     */
    public class func isYesterday(date: Date) -> Bool {
        
        // 2015-12-31 23:59:59 --> 2015-12-31
        // 2016-01-01 00:00:01 --> 2016-01-01
        
        return date.isYesterday()
    }
    
    /**
     *  是否为明天
     */
    public class func isTomorrow(date: Date) -> Bool {
        
        return date.isTommorow()
    }
    
    /**
     * 获取日期的时间戳
     */
    public class func getTimeStampWithDate(date: Date) -> TimeInterval {
        
        return date.timeIntervalSince1970
    }
    
    /**
     * 获取时间戳对应的日期
     */
    public class func getDateWithTimeStamp(timeStamp: TimeInterval) -> Date {
        
        return Date(timeIntervalSince1970: timeStamp)
    }
}


// MARK: - Date分类

extension Date {
    
    // MARK: - fromDate toDate 结果应该是 (toDate - fromDate)
    
    // MARK: - 类方法
    
    /**
     *  计算从startTingDate到resultDate相差的时间
     */
    public static func deltaFromeDate(startTingDate: Date, toDate: Date) -> DateComponents {
        
        // 日历
        let calendar = Calendar.current
        
        // 比较时间
        let componentsSet = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
        
        return calendar.dateComponents(componentsSet, from: startTingDate, to: toDate)
    }
    
    // MARK: - 对象方法
    
    /**
     *  对象方法,计算从date到调用对象相差的时间
     */
    public func deltaFromDate(date: Date) -> DateComponents {
        
        // 日历
        let calendar = Calendar.current
        
        // 比较时间
        let componentsSet = Set<Calendar.Component>([.year, .month, .day, .hour, .minute, .second])
        
        return calendar.dateComponents(componentsSet, from: date, to: self)
    }
    
    /**
     *  是否为今年
     */
    public func isThisYear() -> Bool {
        
        // 日历
        let calendar = Calendar.current
        
        let componentSet = Set<Calendar.Component>([.year])
        
        let nowCmps = calendar.dateComponents(componentSet, from: Date())
        let selfCmps = calendar.dateComponents(componentSet, from: self)
        
        return nowCmps.year  == selfCmps.year
    }
    
    /**
     *  是否为今天第一种方法
     */
//    public func isToday1() -> Bool { // 年月日都一样才是今天
//
//        let calendar = Calendar.current
//
//        let componentSet = Set<Calendar.Component>([.year, .month, .day])
//
//        let nowCmps = calendar.dateComponents(componentSet, from: Date())
//        let selfCmps = calendar.dateComponents(componentSet, from: self)
//
//        return nowCmps.year  == selfCmps.year &&
//            nowCmps.month == selfCmps.month &&
//            nowCmps.day   == selfCmps.day
//    }
    
    /**
     *  是否为今天第二种方法
     */
    public func isToday() -> Bool { // 年月日都一样才是今天
        
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd"
        
        let nowStr = fmt.string(from: Date())
        let selfStr = fmt.string(from: self)
        
        return nowStr == selfStr
    }
    
    /**
     *  是否为昨天
     */
    public func isYesterday() -> Bool {
        
        // 2015-12-31 23:59:59 --> 2015-12-31
        // 2016-01-01 00:00:01 --> 2016-01-01
        
        //日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd"
        
        // 将日期格式转换为不带时分秒的
        let nowDate = fmt.date(from: fmt.string(from: Date()))
        let selfDate = fmt.date(from: fmt.string(from: self))
        
        // 计算相差日期
        let calendar = Calendar.current
        
        let componentSet = Set<Calendar.Component>([.year, .month, .day])
        
        let cmps = calendar.dateComponents(componentSet, from: selfDate!, to: nowDate!)
        //    NSDateComponents *cmps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0]
        
        return cmps.year  == 0 &&
            cmps.month == 0 &&
            cmps.day   == 1
    }
    
    /**
     *  是否为明天
     */
    public func isTommorow() -> Bool {
        
        // 2015-12-31 23:59:59 --> 2015-12-31
        // 2016-01-01 00:00:01 --> 2016-01-01
        
        //日期格式
        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd"
        
        // 将日期格式转换为不带时分秒的
        let nowDate = fmt.date(from: fmt.string(from: Date()))
        let selfDate = fmt.date(from: fmt.string(from: self))
        
        // 计算相差日期
        let calendar = Calendar.current
        
        let componentSet = Set<Calendar.Component>([.year, .month, .day])
        
        let cmps = calendar.dateComponents(componentSet, from: selfDate!, to: nowDate!)
        //    NSDateComponents *cmps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0]
        
        return cmps.year  == 0 &&
            cmps.month == 0 &&
            cmps.day   == -1
    }
    
    public func getTimeStamp() -> TimeInterval {
        
        return timeIntervalSince1970
    }
}
